import requests
import json
import logging
from django.conf import settings
import time
from typing import List
from cozepy import Coze, TokenAuth, Stream, WorkflowEvent, WorkflowEventType, COZE_CN_BASE_URL

logger = logging.getLogger(__name__)


class CozeWorkflowService:
    def __init__(self):
        self.api_base_url = getattr(settings, 'COZE_API_BASE_URL', 'https://api.coze.com')
        self.api_token = getattr(settings, 'COZE_API_TOKEN', '')
        self.workflow_id = getattr(settings, 'COZE_WORKFLOW_ID', '')
        self.agent_id = getattr(settings, 'COZE_AGENT_ID', '')
        self.coze = Coze(auth=TokenAuth(token=self.api_token), base_url=COZE_CN_BASE_URL)

    def optimize_speech_text(self, audio_file):
        try:
            audio_file.seek(0)
            audio_content = audio_file.read()

            headers = {
                'Authorization': f'Bearer {self.api_token}'
            }

            url = f"{self.api_base_url}/open_api/v1/chat"

            data = {
                'bot_id': self.agent_id,
                'stream': False,
                'auto_save_history': True,
            }

            additional_messages = [
                {
                    'role': 'user',
                    'content': '请处理这段语音',
                    'content_type': 'text'
                }
            ]

            files = {
                'file': (getattr(audio_file, 'name', 'audio.webm'), audio_content, 'audio/webm'),
                'additional_messages': (None, json.dumps(additional_messages), 'application/json')
            }

            response = requests.post(url, files=files, headers=headers, timeout=60)
            if response.status_code == 200:
                result = response.json()

                if result.get('code') == 0:
                    messages = result.get('messages', [])
                    assistant_message = None
                    for msg in reversed(messages):
                        if msg.get('role') == 'assistant':
                            assistant_message = msg
                            break

                    if assistant_message:
                        content = assistant_message.get('content', '')
                        try:
                            parsed_content = json.loads(content)
                            return {
                                'success': True,
                                'original_text': parsed_content.get('original_text', ''),
                                'optimized_text': parsed_content.get('optimized_text', content),
                                'confidence': parsed_content.get('confidence', 0.9),
                                'processing_time': parsed_content.get('processing_time', 0)
                            }
                        except json.JSONDecodeError:
                            return {
                                'success': True,
                                'original_text': '',
                                'optimized_text': content,
                                'confidence': 0.9,
                                'processing_time': 0
                            }
                    else:
                        return {
                            'success': False,
                            'error': '未找到智能体回复'
                        }
                else:
                    logger.error(f"Coze智能体执行失败: {result.get('msg')}")
                    return {
                        'success': False,
                        'error': result.get('msg', '智能体执行失败')
                    }
            elif response.status_code == 429:
                logger.error("Coze API调用频率超限")
                return {
                    'success': False,
                    'error': 'API调用频率超限，请稍后重试'
                }
            elif response.status_code == 500:
                logger.error("Coze API服务器内部错误")
                return {
                    'success': False,
                    'error': 'Coze服务内部错误，请稍后重试'
                }
            elif response.status_code == 503:
                logger.error("Coze API服务暂时不可用")
                return {
                    'success': False,
                    'error': 'Coze服务暂时不可用，请稍后重试'
                }
            else:
                logger.error(f"Coze API调用失败: {response.status_code} - {response.text}")
                return {
                    'success': False,
                    'error': f'API调用失败: {response.status_code}'
                }

        except Exception as e:
            logger.error(f"Coze智能体调用异常: {str(e)}")
            return {
                'success': False,
                'error': f'服务异常: {str(e)}'
            }

    def _run_workflow(self, text: str) -> List[str]:
        """
        运行工作流并处理事件流

        Args:
            text (str): 输入到工作流的文本参数

        Returns:
            List[str]: 包含工作流执行过程中产生的所有消息的列表，包括普通消息、错误信息等
        """
        messages: List[str] = []

        def handle_stream(stream: Stream[WorkflowEvent]):
            # 遍历事件流并根据事件类型进行相应处理
            for event in stream:
                if event.event == WorkflowEventType.MESSAGE:
                    # 处理普通消息事件，将消息内容添加到消息列表中
                    messages.append(event.message.content)
                elif event.event == WorkflowEventType.ERROR:
                    # 处理错误事件，将错误信息格式化后添加到消息列表中
                    messages.append(f"[ERROR] {event.error}")
                elif event.event == WorkflowEventType.INTERRUPT:
                    # 处理中断事件，恢复工作流执行并递归处理新的事件流
                    handle_stream(
                        self.coze.workflows.runs.resume(
                            workflow_id=self.workflow_id,
                            event_id=event.interrupt.interrupt_data.event_id,
                            resume_data="continue",
                            interrupt_type=event.interrupt.interrupt_data.type,
                        )
                    )

        # 启动工作流并获取事件流，然后调用处理函数处理事件
        handle_stream(
            self.coze.workflows.runs.stream(
                workflow_id=self.workflow_id,
                parameters={"input": text}
            )
        )
        return messages

    def generate_meeting_summary(self, meeting_texts, meeting_description=""):
        try:
            # 添加会议描述到会议内容中
            description_text = f"会议描述：{meeting_description if meeting_description else '暂无'}\n\n"

            full_content = description_text + '\n\n'.join([
                f"[{item.get('timestamp', '')}] {item.get('speaker', '')}: {item.get('text', '')}"
                for item in meeting_texts
            ])

            logger.info(f"准备生成会议总结，内容长度: {len(full_content)} 字符")

            if self.workflow_id:
                try:
                    logger.info(f"使用工作流生成会议总结，工作流ID: {self.workflow_id}")
                    workflow_messages = self._run_workflow(full_content)

                    valid_messages = [msg for msg in workflow_messages if not msg.startswith('[ERROR]')]
                    if valid_messages:
                        summary_content = '\n'.join(valid_messages)
                        logger.info(f"工作流生成总结成功，总结长度: {len(summary_content)} 字符")
                        # 移除可能的Markdown标记
                        clean_summary = self._remove_markdown_formatting(summary_content)
                        return {
                            'success': True,
                            'summary': clean_summary,
                            'key_points': [],
                            'action_items': [],
                            'meeting_duration': '',
                            'word_count': len(clean_summary)
                        }
                    else:
                        logger.warning("工作流未返回有效消息，检查错误信息")
                        error_messages = [msg for msg in workflow_messages if msg.startswith('[ERROR]')]
                        if error_messages:
                            error_msg = error_messages[0]
                            if "permission" in error_msg.lower() or "权限" in error_msg:
                                logger.warning("检测到权限问题，直接回退到智能体方式")
                                return self._generate_summary_with_agent(full_content)

                        logger.warning("工作流执行未返回有效结果，回退到智能体方式")
                        return self._generate_summary_with_agent(full_content)
                except Exception as e:
                    logger.error(f"工作流执行失败: {str(e)}")
                    return self._generate_summary_with_agent(full_content)
            else:
                logger.info("使用智能体生成会议总结")
                return self._generate_summary_with_agent(full_content)

        except Exception as e:
            logger.error(f"会议总结生成异常: {str(e)}")
            return {
                'success': False,
                'error': f'总结生成异常: {str(e)}'
            }

    def _generate_summary_with_agent(self, full_content):
        try:
            headers = {
                'Authorization': f'Bearer {self.api_token}',
                'Content-Type': 'application/json'
            }

            url = f"{self.api_base_url}/open_api/v2/chat"

            data = {
                'bot_id': self.agent_id,
                'stream': False,
                'auto_save_history': True,
                'additional_messages': [
                    {
                        'role': 'user',
                        'content': f'请为以下会议内容生成总结，包括关键要点和行动项。请以纯文本格式返回，不要使用Markdown或其他格式标记:\n\n{full_content}',
                        'content_type': 'text'
                    }
                ]
            }

            response = requests.post(url, json=data, headers=headers, timeout=120)
            if response.status_code == 200:
                result = response.json()

                if result.get('code') == 0:
                    messages = result.get('messages', [])
                    assistant_message = None
                    for msg in reversed(messages):
                        if msg.get('role') == 'assistant':
                            assistant_message = msg
                            break

                    if assistant_message:
                        content = assistant_message.get('content', '')
                        try:
                            parsed_content = json.loads(content)
                            # 确保返回纯文本格式的总结
                            summary_text = parsed_content.get('summary', content)
                            # 移除可能的Markdown标记
                            summary_text = self._remove_markdown_formatting(summary_text)

                            key_points = parsed_content.get('key_points', [])
                            # 确保关键要点也是纯文本格式
                            key_points = [self._remove_markdown_formatting(point) for point in key_points]

                            return {
                                'success': True,
                                'summary': summary_text,
                                'key_points': key_points,
                                'action_items': parsed_content.get('action_items', []),
                                'meeting_duration': parsed_content.get('meeting_duration', ''),
                                'word_count': parsed_content.get('word_count', len(summary_text))
                            }
                        except json.JSONDecodeError:
                            # 移除可能的Markdown标记
                            clean_content = self._remove_markdown_formatting(content)
                            return {
                                'success': True,
                                'summary': clean_content,
                                'key_points': [],
                                'action_items': [],
                                'meeting_duration': '',
                                'word_count': len(clean_content)
                            }
                    else:
                        return {
                            'success': False,
                            'error': '未找到智能体回复'
                        }
                else:
                    error_msg = result.get('msg', '总结生成失败')
                    logger.error(f"会议总结生成失败: {error_msg}")

                    if "server issues" in error_msg.lower():
                        return {
                            'success': False,
                            'error': 'Coze服务暂时不可用，请稍后重试或联系技术支持'
                        }
                    elif "token" in error_msg.lower():
                        return {
                            'success': False,
                            'error': 'API令牌无效，请检查配置'
                        }
                    elif "bot_id" in error_msg.lower():
                        return {
                            'success': False,
                            'error': '智能体ID无效，请检查配置'
                        }
                    else:
                        return {
                            'success': False,
                            'error': error_msg
                        }
            elif response.status_code == 429:
                logger.error("会议总结API调用频率超限")
                return {
                    'success': False,
                    'error': 'API调用频率超限，请稍后重试'
                }
            elif response.status_code == 500:
                logger.error("会议总结API服务器内部错误")
                return {
                    'success': False,
                    'error': 'Coze服务内部错误，请稍后重试或联系技术支持'
                }
            elif response.status_code == 503:
                logger.error("会议总结API服务暂时不可用")
                return {
                    'success': False,
                    'error': 'Coze服务暂时不可用，请稍后重试'
                }
            else:
                logger.error(f"总结API调用失败: {response.status_code} - {response.text}")
                return {
                    'success': False,
                    'error': f'总结生成失败: {response.status_code} - {response.text[:100]}'
                }

        except Exception as e:
            logger.error(f"会议总结生成异常: {str(e)}")
            return {
                'success': False,
                'error': f'总结生成异常: {str(e)}'
            }

    def _remove_markdown_formatting(self, text):
        """移除文本中的Markdown格式标记"""
        import re
        if not isinstance(text, str):
            return str(text)

        # 移除Markdown标题标记
        text = re.sub(r'^#+\s*', '', text, flags=re.MULTILINE)
        # 移除粗体标记
        text = re.sub(r'\*\*(.*?)\*\*', r'\1', text)
        text = re.sub(r'__(.*?)__', r'\1', text)
        # 移除斜体标记
        text = re.sub(r'\*(.*?)\*', r'\1', text)
        text = re.sub(r'_(.*?)_', r'\1', text)
        # 移除代码块标记
        text = re.sub(r'`([^`]+)`', r'\1', text)
        # 移除链接标记，保留链接文本
        text = re.sub(r'\[([^\]]+)\]\([^\)]+\)', r'\1', text)
        # 移除多余的星号
        text = re.sub(r'\*+', '', text)
        # 移除多余的空白行
        text = re.sub(r'\n\s*\n', '\n\n', text)

        return text.strip()


def get_coze_service():
    return CozeWorkflowService()